package displayboardinfo.entities;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

/**
 *  
 * Klasa reprezentująca pojedynczego użytkownika systemu.
 * Użytkownikami systemu są: rejestratorzy, lekarze oraz ekrany umieszczone przed gabinetami.
 *
 * @author Artur Jaworski
 */
@Entity
@Table ( name = "Users", uniqueConstraints = {@UniqueConstraint(columnNames={"login"})} )
@XmlRootElement
@XmlType(propOrder = { "id", "login", "password", "name", "surname", "userType", "rooms", "admissions" })
public class User {
	@Id
	@Column ( name = "id" )
	@GeneratedValue(strategy=GenerationType.AUTO)
	protected long id;
	
	@Column ( name = "login", nullable = false )
	protected String login;
	
	@Column ( name = "password", nullable = false )
	protected String password;
	
	@Column ( name = "name", nullable = false )
	protected String name;
	
	@Column ( name = "surname", nullable = false )
	protected String surname;
	
	@Column ( name = "user_type", nullable = false )
	protected String userType;
	
	@ManyToMany
	@JoinTable ( name = "Privileges", joinColumns = {@JoinColumn ( name = "id_user")}, inverseJoinColumns = {@JoinColumn ( name = "id_room" )} )
	protected List<Room> rooms;
	
	@OneToMany ( mappedBy = "user" )
	protected List<Admission> admissions;

	/**
	 * Domyślny konstruktor bezargumentowy.
	 */
	public User() {
	
	}
	
	/**
	 * Pobranie unikalnego numeru ID użytkownika. 
	 * 
	 * @return unikalny numer ID
	 */
	public long getId() {
		return id;
	}

	/**
	 * Ustawienie unikalnego numeru ID użytkownika.
	 * Ręczne ustawianie numeru ID powinno być zawsze robione z rozwagą. 
	 * 
	 * @param id unikalny numer ID
	 */
	public void setId(long id) {
		this.id = id;
	}

	/**
	 * Pobranie loginu użytkownika.
	 * 
	 * @return login użytkownika
	 */
	public String getLogin() {
		return login;
	}

	/**
	 * Ustawienie loginu użytkownika.
	 * 
	 * @param login login użytkownika
	 */
	public void setLogin(String login) {
		this.login = login;
	}

	/**
	 * Pobranie hasła użytkownika.
	 * Hasło jest przechowywane w formie hasha SHA-1.
	 * 
	 * @return hasło użytkownika
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * Ustawienie hasła użytkownika.
	 * Hasło jest przechowywane w formie hasha SHA-1.
	 * 
	 * @param password hasło użytkownika
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * Pobranie imienia użytkownika.
	 * 
	 * @return imię użytkownika
	 */
	public String getName() {
		return name;
	}

	/**
	 * Ustawienie imienia użytkownika.
	 * 
	 * @param name imię użytkownika
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Pobranie nazwiska użytkownika.
	 * 
	 * @return nazwisko użytkownika
	 */
	public String getSurname() {
		return surname;
	}

	/**
	 * Ustawienie nazwiska użytkownika.
	 * 
	 * @param surname nazwisko użytkownika
	 */
	public void setSurname(String surname) {
		this.surname = surname;
	}

	/**
	 * Pobranie typu użytkownika.
	 * d - lekarz [doctor], r - rejestrator [register], s - ekran [screen]
	 * 
	 * @return typ użytkownika
	 */
	public String getUserType() {
		return userType;
	}

	/**
	 * Ustawienie typu użytkownika.
	 * d - lekarz [doctor], r - rejestrator [register], s - ekran [screen]
	 * 
	 * @param userType typ użytkownika
	 */
	public void setUserType(String userType) {
		this.userType = userType;
	}
	
	/**
	 * Pobranie listy gabinetów, do których użytkownik ma uprawnienia.
	 * 
	 * @return lista gabinetów, do których użytkownik ma uprawnienia.
	 */
	@XmlElementWrapper ( name = "rooms" )
	@XmlElement ( name = "room" )
	public List<Room> getRooms() {
		return rooms;
	}

	/**
	 * Ustawienie listy gabinetów, do których użytkownik ma uprawnienia.
	 * 
	 * @param rooms lista gabinetów, do których użytkownik ma uprawnienia.
	 */
	public void setRooms(List<Room> rooms) {
		this.rooms = rooms;
	}

	/**
	 * Pobranie listy okresów przyjęć użytkownika.
	 * Metoda ta ma sens tylko w przypadku lekarzy, pozostali użytkownicy nie mają okresów przyjęć.
	 * 
	 * @return lista okresów przyjęć użytkownika
	 */
	@XmlElementWrapper ( name = "admissions" )
	@XmlElement ( name = "admission" )
	public List<Admission> getAdmissions() {
		return admissions;
	}

	/**
	 * Ustawienie listy okresów przyjęć użytkownika.
	 * Metoda ta ma sens tylko w przypadku lekarzy, pozostali użytkownicy nie mają okresów przyjęć.
	 * 
	 * @param admissions lista okresów przyjęć użytkownika
	 */
	public void setAdmissions(List<Admission> admissions) {
		this.admissions = admissions;
	}

	/**
	 * Konwersja obiektu użytkownika na łatwy do zrozumienia łańcuch znaków.
	 * 
	 * @return sformatowany łańcuch znaków
	 */
	@Override
	public String toString() {
		String text = new String();
		
		text += "\nid:" + id + "\n" +
				"login:" + login + "\n" +
				"password:" + password + "\n" +
				"name:" + name + "\n" +
				"surname:" + surname + "\n" +
				"userType:" + userType;
		if (rooms != null && rooms.size() > 0){
				text += "\nrooms:";
			for (Room r : rooms)
				text += r.getId() + ",";
		}
		if (admissions != null && admissions.size() > 0){
			text += "\nadmissions:";
			for (Admission a : admissions)
				text += a.getId() + ",";
		}
		
		return text;
	}
	
	
}
